/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package _examples;

/**
 *
 * @author vincent
 */
import static _examples.PRouteNode.macstatic;
import gui.simgui;
import javax.swing.JOptionPane;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.Queue;
import java.util.Vector;

import jbotsim.Clock;
import jbotsim.Message;
import jbotsim.Messagebr;
import jbotsim.Node;
import jbotsim.Topology;
import jbotsim.event.ClockListener;
import jbotsim.event.MessageListener;
import jbotsim.event.MessagebrListener;
//RWPNode ���ƶ�����
public class aodvnode extends RWPNode implements ClockListener, MessagebrListener {

    aodvnode ttnode;
    public static int macstatic = 0;
    int lastFatherHello = 0 - global.FATHERLOSTTIMER;
    int helloBefore = 0;
    int requestBefore = 0;
    long fatheraddr = 0;
    int fatherid = 0;
    int fathermac = 0;
    long addr = 1;
    int id = 1;
    int mac = 0;
    int level = 0;
    int round = 0;
    int prim = 1;
    Vector<potFatherinfo> potfathervector = new Vector<potFatherinfo>();
    Vector<nodeinfo> childvec = new Vector<nodeinfo>();
    Vector<nodeinfo> nodevec = new Vector<nodeinfo>();
    int potfathermac = 0;
    public boolean worked;
    boolean canmove;
    int pinground = 0;
    int timebeg = 0;
    int timeend = 0;
    int pingsendnum = 0;
    int pingrecvnum = 0;
    int recvpinground = 0;
    boolean inping = false;
    simgui mainframe;
    int sendjobid;
    int sendall;
    int clientdesid;
    int senddatabeg;
    int reallysend = 0;
    int sendthis = 0;
    int lastsendstime;
    long clientdesaddr;
    int insend = 0;
    int hangid;
    boolean needqaddr;
    int qlevel;
    int prpktnum;
    int brpktnum;
    int maxjmp;
    String brpkt;
    String prpkt;
    boolean findbr;
    String clientaddrpath;
    int insendbr;
    int sendthisbr;
    int lastsendstimebr;
    int reallysendbr;
    int clientdesmac;
    int lastclocktime = 0;

    public aodvnode() {

        super();
        //  JOptionPane.showInputDialog("proutenode" );
        //System.out.print(macstatic);
        insendbr = 0;
        mac = macstatic;
        macstatic++;
        if (mac == 0) {
            return;
        }

        Clock.addClockListener(this, global.TIMEPERCLOCK);

        super.addMessagebrListener(this);
        if (mac == 1) {
            worked = true;
            canmove = false;

            this.setprmac(mac);
            // global.jv2.addnode(this);
        } else {
            this.setprmac(mac);
            worked = false;
            canmove = false;
            //	  global.jv.addnode(this);
        }
        //   JOptionPane.showInputDialog("aodvnode" );
    }

    public void onClock() {
        this.clrnuminclock();
        if (id == 1) {
        } else {
            super.onClock();
        }

      //  global.jv.moveteams1();
        if ((Clock.currentTime() - lastsendstimebr) > (maxjmp * global.MAXWAITSENDS) && insendbr == 1) {

            begqaddrbr();


        }

    }

    public void begsendbr(int desmac, int datalen, aodvnode t, int i) {
        brpkt = "";
        prpkt = "";
        prpktnum = 0;
        brpktnum = 0;
        maxjmp = 5;

        clientdesmac = desmac;
        clientaddrpath = "";
        if (insendbr == 1) {
            JOptionPane.showInputDialog("节点id " + id + " 正在向节点id " + clientdesid + " 发送数据，请求被忽略");
            return;
        }
        insendbr = 1;
        lastsendstimebr = Clock.currentTime();
        senddatabeg = Clock.currentTime();
        this.setProperty("color", "ORANGE");


        needqaddr = true;
        //     mainframe=mainframe1;
        sendjobid = i;
        //  app=new jprocessbar(desid);
        insend = 1;
        sendall = datalen;
        reallysend = 0;

        ttnode = t;
        ttnode.setProperty("color", "ORANGE");
        ttnode.marksend();
        lastsendstime = Clock.currentTime();


        sendnextbr();

        begqaddrbr();
        // sendnext();
    }

    public void begqaddrbr() {
        //  JOptionPane.showInputDialog("beg q addr");
        clientdesaddr = -1;
        global.brfind = false;
        int lv = 0;
        maxjmp++;
        this.sendbr(null, "BRQES srcid:" + mac + " desid:" + clientdesmac + " path:" + mac + ", lv:" + lv + " max:" + maxjmp + " ");

    }

    public void sendnextbr() {
        /*
         if(mac==1)
         {
         clientdesaddr=finddesaddrfromid(clientdesid);
         }
         else
         {
         if(clientdesaddr==-1)
         return;
         }*/
        if (clientaddrpath == "") {
            return;
        }
        lastsendstimebr = Clock.currentTime();
        //senddatabeg=Clock.currentTime();

        sendthisbr = 0;
        int i = 0;

        //       JOptionPane.showInputDialog("ready send");
        int sendnum = 0;
        int pktid;
        int desmac;


        int nextmac;
        String[] sArray = clientaddrpath.split(",");

        nextmac = Integer.parseInt(sArray[1]);
        for (i = 0; i < global.TIMEPERSENDS; i++) {


            if ((reallysendbr + sendthisbr) >= sendall) {
                // sendnum=sendremain+MAXPERSEND;
                sendthis = sendall - reallysendbr;
                pktid = 0;

                this.sendbr(null, "DTBRS  srcid:" + mac + " desid:" + clientdesmac + " path:" + clientaddrpath + " ptkid:" + pktid + " nextmac:" + nextmac + " ");
                return;
            } else {
                // sendnum=MAXPERSEND;
                sendthisbr += global.MAXPERSEND;
                pktid = 1;

                this.sendbr(null, "DTBRS  srcid:" + mac + " desid:" + clientdesmac + " path:" + clientaddrpath + " ptkid:" + pktid + " nextmac:" + nextmac + " ");
            }
        }
        pktid = 0;

        this.sendbr(null, "DTBRS  srcid:" + mac + " desid:" + clientdesmac + " path:" + clientaddrpath + " ptkid:" + pktid + " nextmac:" + nextmac + " ");
    }

    public void recvupbr() {

        if (insendbr == 0) {
            return;
        }
        //JOptionPane.showInputDialog("recvup  "+sendthis+"  and reallysend "+(reallysend+sendthis));
        if ((reallysendbr + sendthisbr) >= sendall) {
            mainframe.processbarchange(sendjobid + 4, 100);
            insendbr = 0;
            //   this.setProperty("color", "green");
            //   this.unmarksend();


            //    mainframe.addtext(1,prpkt);
            //   mainframe.addtext(2,brpkt);
            //	ttnode.unmarksend();
            JOptionPane.showInputDialog("br send all data over!!! use time" + (Clock.currentTime() - senddatabeg));
            mainframe.processbarchange(sendjobid + 4, 0);
            //System.out.print("send all data over!!! use time"+(Clock.currentTime()-senddatabeg));
        } else {
            reallysendbr += sendthisbr;
            int mm = reallysendbr * 100 / sendall;
            mainframe.processbarchange(sendjobid + 4, mm);
            // JOptionPane.showInputDialog("recv up" );
            //   mainframe.processbarchange(sendjobid, mm);
            //	JOptionPane.showInputDialog(mm+" "+reallysend+"  "+sendall);

            sendnextbr();
        }


    }

    public void begqaddr(int qid) {
        //  JOptionPane.showInputDialog("beg q addr");
        clientdesaddr = -1;
        global.brfind = false;
        int lv = 0;
        this.send(null, "BRQEST srcid:" + id + " desid:" + clientdesid + " path:" + id + ", lv:" + lv + " ");
        this.send(null, "QDEST  srcaddr:" + addr + " desaddr:" + 1 + " desid:" + 1 + " desmac:" + fathermac + " srcid:" + id + " qid:" + qid + " qaddr:" + 0 + " level:" + qlevel + " ");
    }

    public void dobrrequestrly(Messagebr msg) {
        // ,"BRQERR srcid:"+desid+" desid:"+srcid+" path:"+path[0]+id+", lv:"+lv+" maxjmp:"+maxjmpt+" nextid:"+Integer.parseInt(stmp[stmp.length-1])+" ");
        //  this.send(null,"BRQEST srcid:"+id+"desid:"+clientdesid+" path:"+id+", lv:"+lv+" ");
        String[] sArray = msg.toStringPR().split(":");
        String[] stmp1 = sArray[1].split(" ");
        int srcmac = Integer.parseInt(stmp1[0]);
        String[] stmp2 = sArray[2].split(" ");
        int desmac = Integer.parseInt(stmp2[0]);
        String[] path = sArray[3].split(" ");


        String[] stmp4 = sArray[4].split(" ");
        int lv = Integer.parseInt(stmp4[0]);
        String[] stmp5 = sArray[5].split(" ");
        int maxjmpt = Integer.parseInt(stmp5[0]);
        String[] stmp6 = sArray[6].split(" ");
        int nextmac = Integer.parseInt(stmp6[0]);

        if (lv < 0) {
            return;
        }

        String[] stmp = path[0].split(",");
        // JOptionPane.showInputDialog(path[0] );
        int i;
        int lastid = 0;
        int premac = -1;



        if (desmac == mac && clientaddrpath == "" && insend == 1) {


            //this.sendbr(null,"BRQERR srcid:"+id+" desid:"+clientdesid+" path:"+path+id+", lv:"+lv+" maxjmp:"+maxjmpt+" nextid:"+Integer.parseInt(stmp[stmp.length-1])+" ");

            clientaddrpath = path[0];
            sendnextbr();
            //    global.brfind=true;
        } else if (mac == nextmac) {


            //  mainframe.addtext(2, lastid,id);

            brpktnum++;
            //   brpkt=brpkt+lastid+"->"+id+",";
            if (brpktnum % 10 == 0) {
                //  mainframe.settext(2, brpktnum); 
            }

            lv--;
            this.sendbr(null, "BRQERR srcid:" + srcmac + " desid:" + desmac + " path:" + path[0] + mac + ", lv:" + lv + " maxjmp:" + maxjmpt + " nextid:" + stmp[lv] + " ");
            //      JOptionPane.showInputDialog(stmp[stmp.length-1] );



        }


    }

    public void dobrrequest(Messagebr msg) {

        //  this.send(null,"BRQEST srcmac:"+mac+"desmac:"+clientdesmac+" path:"+mac+", lv:"+lv+" ");
        String[] sArray = msg.toStringPR().split(":");
        String[] stmp1 = sArray[1].split(" ");
        int srcmac = Integer.parseInt(stmp1[0]);
        String[] stmp2 = sArray[2].split(" ");
        int desmac = Integer.parseInt(stmp2[0]);
        String[] path = sArray[3].split(" ");


        String[] stmp4 = sArray[4].split(" ");
        int lv = Integer.parseInt(stmp4[0]);
        String[] stmp5 = sArray[5].split(" ");
        int maxjmpt = Integer.parseInt(stmp5[0]);


        if (maxjmpt < lv) {
            return;
        }

        String[] stmp = path[0].split(",");
        int i;
        int lastmac = 0;
        int premac = -1;
        for (i = 0; i < stmp.length - 1; i++) {
            lastmac = Integer.parseInt(stmp[i]);
            if (stmp[i].equals(String.valueOf(mac))) {
                if (i != 0) {
                    // premac=Integer.parseInt(stmp[i-1]);
                }
                return;
            }
        }


        if (desmac == mac) {
            if (premac != -1) {
                //bug
            } else {
                lv++;
                this.sendbr(null, "BRQERR srcmac:" + desmac + " desmac:" + srcmac + " path:" + path[0] + mac + ", lv:" + lv + " maxjmp:" + maxjmpt + " nextmac:" + Integer.parseInt(stmp[stmp.length - 1]) + " ");
            }

            //    global.brfind=true;
        } else {


            //  mainframe.addtext(2, lastmac,mac);

            brpktnum++;
            brpkt = brpkt + lastmac + "->" + mac + ",";
            if (brpktnum % 10 == 0) {
                //mainframe.settext(2, brpktnum); 
            }

            lv++;
            this.sendbr(null, "BRQEST srcmac:" + srcmac + " desmac:" + desmac + " path:" + path[0] + mac + ", lv:" + lv + " maxjmp:" + maxjmpt + " ");
        }





    }

    public void dobrdatarly(Messagebr msg) {
        //    "DTBRR  srcmac:"+desmac+" desmac:"+srcmac+" path:"+tmps+" ptkmac:" +pktmac+" jmp:"+0+" 
        ;
        String[] sArray = msg.toStringPR().split(":");
        String[] stmp1 = sArray[1].split(" ");
        int srcmac = Integer.parseInt(stmp1[0]);
        String[] stmp2 = sArray[2].split(" ");
        int desmac = Integer.parseInt(stmp2[0]);
        String[] path = sArray[3].split(" ");


        String[] stmp4 = sArray[4].split(" ");
        int pktmac = Integer.parseInt(stmp4[0]);
        String[] stmp5 = sArray[5].split(" ");
        int jmp = Integer.parseInt(stmp5[0]);




        String[] stmp = path[0].split(",");




        if (jmp < 0) {
            return;
        }

        if (desmac == mac && insendbr == 1) {
            if (pktmac == 0) {
                recvupbr();
            }


        } else {
            jmp--;
            this.sendbr(null, "DTBRR  srcmac:" + srcmac + " desmac:" + desmac + " path:" + path[0] + " ptkmac:" + pktmac + " jmp:" + jmp + " ");
        }


    }

    public void dobrdata(Messagebr msg) {
        //   this.sendbr(null, "DTBRS  srcmac:"+mac+" desmac:"+clientdesmac+" path:"+clientaddrpath+" ptkmac:" +pktmac+" ");
        //  this.send(null,"BRQEST srcmac:"+mac+"desmac:"+clientdesmac+" path:"+mac+", lv:"+lv+" ");
        String[] sArray = msg.toStringPR().split(":");
        String[] stmp1 = sArray[1].split(" ");
        int srcmac = Integer.parseInt(stmp1[0]);
        String[] stmp2 = sArray[2].split(" ");
        int desmac = Integer.parseInt(stmp2[0]);
        String[] path = sArray[3].split(" ");


        String[] stmp4 = sArray[4].split(" ");
        int pktid = Integer.parseInt(stmp4[0]);
        String[] stmp5 = sArray[5].split(" ");
        int nextmac = Integer.parseInt(stmp5[0]);

        if (nextmac != mac) {
            return;
        }


        String[] stmp = path[0].split(",");

        int i = 0;
        int macthis = -1;
        for (i = 0; i < stmp.length - 1; i++) {

            if (stmp[i].equals(String.valueOf(mac))) {
                macthis = Integer.parseInt(stmp[i + 1]);
                break;
            }
        }



        if (desmac == mac) {

            if (pktid == 0) {
                this.sendbr(null, "DTBRR  srcmac:" + desmac + " desmac:" + srcmac + " path:" + path[0] + " ptkmac:" + pktid + " jmp:" + (stmp.length - 1) + " ");
            }
        } else {

            this.sendbr(null, "DTBRS  srcmac:" + srcmac + " desmac:" + desmac + " path:" + path[0] + " ptkmac:" + pktid + " nextmac:" + macthis + " ");
        }


    }

    public void onMessagebr(Messagebr msg) {


        // System.out.print(msg.toStringPR());
        String cmd = msg.toStringPR().substring(0, 5);
        super.addnuminclock();
        if (cmd.equals("BRQES")) {
            dobrrequest(msg);
        } else if (cmd.equals("BRQER")) {
            dobrrequestrly(msg);
        } else if (cmd.equals("DTBRS")) {
            dobrdata(msg);
        } else if (cmd.equals("DTBRR")) {
            dobrdatarly(msg);
        }

    }
}